<template>
  <el-card>
    <el-form :inline="true" class="form">
      <el-form-item label="角色名称">
        <el-input @keyup.enter="search" placeholder="请你输入搜索角色名称"
                  v-model="pageRequest.model.roleName"></el-input>
      </el-form-item>
      <el-form-item style="width: 200px" label="角色状态">
        <el-select
            v-model="pageRequest.model.status"
            placeholder="请选择状态"
            clearable>
          <el-option label="启用" :value="0"></el-option>
          <el-option label="禁用" :value="1"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item style="width: 200px" label="角色权限">
        <el-select
            v-model="pageRequest.model.roleKey"
            placeholder="请您选择角色权限"
            clearable
        >
          <el-option
              v-for="(label, key) in roleKeyMap"
              :key="key"
              :label="label"
              :value="key"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="default" @click="search">
          搜索
        </el-button>
        <el-button type="primary" size="default" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <el-card style="margin: 10px 0px;">
    <el-button icon="Plus" type="primary" plain size="default" v-hasPermi="['role_add']" @click="addRole">新增
    </el-button>
    <el-button icon="Delete" type="danger" plain size="default" :disabled="selectIdArr.length ? false : true"
               v-hasPermi="['role_delete']"
               @click="deleteSelectRole">删除
    </el-button>
    <el-table @selection-change="selectChange" border style="margin: 10px 0px;" :data="allRole">
      <!--      <el-table-column type="index" align="center" label="#"></el-table-column>-->
      <el-table-column type="selection" align="center"></el-table-column>
      <el-table-column width="100px" label="ID" align="center" prop="id"></el-table-column>
      <el-table-column label="角色名称" align="center" prop="roleName" show-overflow-tooltip></el-table-column>
      <el-table-column label="角色权限" align="center" show-overflow-tooltip>
        <template #default="{ row }">
          <!-- 根据 roleKey 显示对应的中文角色名称 -->
          <span>{{ roleKeyMap[row.roleKey] || '未知权限' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" width="100">
        <template #="scope">
          <el-switch
              v-model="scope.row.status"
              :active-value="0"
              :inactive-value="1"
              @change="handleStatusChange(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column label="操作" width="280px" align="center">
        <!-- row:已有的职位对象 -->
        <template #="{ row, $index }">
          <el-button type="primary" v-if="row.roleName!='超级管理员'" size="small" icon="User"
                     v-hasPermi="['role_update']" @click="setPermisstion(row)">
            分配权限
          </el-button>
          <el-button type="primary" v-if="row.roleName!='超级管理员'" size="small" icon="Edit"
                     v-hasPermi="['role_update']" @click="updateRole(row)">
            编辑
          </el-button>
          <el-button type="primary" v-if="row.roleName!='超级管理员'" size="small" v-hasPermi="['role_delete']"
                     @click="removeRole(row)" icon="Delete">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination v-model:current-page="pageRequest.page.index" v-model:page-size="pageRequest.page.size"
                   :page-sizes="[10, 20, 30, 50]"
                   :background="true" layout="prev, pager, next, jumper,->,sizes,total" :total="total"
                   @current-change="getHasRole"
                   @size-change="handlerRole"/>
  </el-card>
  <!-- 添加职位与更新已有职位的结构:抽屉组件 -->
  <el-drawer v-model="dialogVisite">
    <!-- 头部标题:将来文字内容应该动态的 -->
    <template #header>
      <h4>{{ RoleParams.id ? '更新角色' : '添加角色' }}</h4>
    </template>
    <!-- 身体部分 -->
    <template #default>
      <el-form :model="RoleParams" :rules="rules" ref="form" label-position="right"
               label-width="100px">
        <el-form-item style="width: 300px" label="角色名" prop="roleName">
          <el-input placeholder="请你输入角色名称" v-model="RoleParams.roleName"></el-input>
        </el-form-item>
        <el-form-item style="width: 300px" label="角色权限">
          <el-select
              v-model="RoleParams.roleKey"
              placeholder="请您选择角色权限"
          >
            <el-option
                v-for="(label, key) in roleKeyMap"
                :key="key"
                :label="label"
                :value="key"
            ></el-option>
          </el-select>
        </el-form-item>

        <!-- 添加用户状态的 el-form-item -->
        <el-form-item style="width: 300px" label="角色状态" prop="status">
          <el-radio-group v-model="RoleParams.status">
            <el-radio :label="0">正常</el-radio>
            <el-radio :label="1">停用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="dialogVisite = false">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </template>
  </el-drawer>
  <!-- 抽屉组件:分配职位的菜单权限与按钮的权限 -->
  <el-drawer v-model="drawer">
    <template #header>
      <h4>分配权限</h4>
    </template>
    <template #default>
      <el-form :rules="rules" ref="treeRef" label-position="right"
               label-width="100px">
        <el-form-item style="width: 300px" label="角色名称">
          <el-input disabled v-model="RoleParams.roleName"></el-input>
        </el-form-item>
        <el-form-item style="width: 300px" label="角色权限">
          <el-select
              v-model="menuDto.roleKey"
              placeholder="请您选择角色权限"
          >
            <el-option
                v-for="(label, key) in roleKeyMap"
                :key="key"
                :label="label"
                :value="key"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="menuDto.roleKey==='temporary'" style="width: 400px" label="生效时间">
          <el-date-picker
              v-model="menuDto.roleTime"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
          ></el-date-picker>
        </el-form-item>
        <el-form-item v-if="menuDto.roleKey !== 'admin'" label="数据权限">
          <!--          <div style="margin-bottom: 10px;">
                      <el-checkbox v-model="selectAll" @change="handleSelectAll">{{ !selectAll ? '全选' : '全不选' }}
                      </el-checkbox>
                      <el-checkbox v-model="isExpandAll" @change="handleExpandAll">{{
                          !isExpandAll ? '展开' : '折叠'
                        }}
                      </el-checkbox>
                    </div>-->
          <!-- 树形控件 -->
          <el-tree ref="tree" style="width: 280px" :data="menuArr" show-checkbox node-key="id"
                   :default-expand-all="isExpandAll"
                   :default-checked-keys="selectArr" :props="defaultProps"/>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="drawer = false">取消</el-button>
        <el-button type="primary" @click="handler">确定</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="js">
import {ref, onMounted, reactive, nextTick} from 'vue';
//请求方法

//引入骨架的仓库
import useLayOutSettingStore from '@/store/modules/setting';
import {ElMessage} from 'element-plus';
import {
  reqAddOrUpdateRole,
  reqAllMenuList,
  reqAllRoleList,
  reqRemoveRoles,
  reqSetPermisstion
} from "@/api/system/role";
import modal from "@/utils/modal.js";
import setting from "@/setting.js";

const selectAll = ref(false);
const isExpandAll = ref(true);
let settingStore = useLayOutSettingStore();
//分页查询请求参数
let pageRequest = ref({
  page: {
    index: 1,
    size: 10,
  },
  model: {
    roleName: '',
    roleKey: '',
    status: ''
  }
});
//角色权限类型
let roleKeyMap = ref({
  admin: '所有权限',
  common: '普通权限',
  temporary: '临时权限'
});
//存储全部已有的职位
let allRole = ref([]);
//准备一个数组存储批量删除的用户的ID
let selectIdArr = ref([]);
//职位总个数
let total = ref(0);
//控制对话框的显示与隐藏
let dialogVisite = ref(false);
//获取form组件实例
let form = ref();
let treeRef = ref();
//控制抽屉显示与隐藏
let drawer = ref(false);
//收集新增岗位数据
let RoleParams = reactive({
  roleName: '',
  status: 0,
  roleKey: 'common',
})
//准备一个数组:数组用于存储勾选的节点的ID
let selectArr = ref([]);
//定义数组存储用户权限的数据
let menuArr = ref([]);
let menuDto = ref({
  roleId: '',
  roleKey: '',
  roleTime: '',
  menuIdList: '',
  startTime: '',
  endTime: '',
});
//获取tree组件实例
let tree = ref();
//组件挂载完毕
onMounted(() => {
  //获取职位请求
  getHasRole();
});

const handleSelectAll = () => {

};


const handleExpandAll = () => {

};

//获取全部用户信息的方法|分页器当前页码发生变化的回调
const getHasRole = async (pager = 1) => {
  //修改当前页码
  pageRequest.value.page.index = pager;
  let result = await reqAllRoleList(pageRequest.value);
  if (result.code == setting.SYSTEM_SUCCESS) {
    total.value = result.data.total;
    allRole.value = result.data.items;
  }
}
//table复选框勾选的时候会触发的事件
const selectChange = (value) => {
  selectIdArr.value = value;
}
//下拉菜单的回调
const sizeChange = () => {
  getHasRole();
}
//搜索按钮的回调
const search = () => {
  //再次发请求根据关键字
  getHasRole();
  //keyword.value = '';
}
//重置按钮的回调
const reset = () => {
  settingStore.refsh = !settingStore.refsh;
}
//添加职位按钮的回调
const addRole = () => {
  //对话框显示出来
  dialogVisite.value = true;
  //清空数据
  Object.assign(RoleParams, {
    roleName: '',
    id: 0
  });
  //清空上一次表单校验错误结果
  nextTick(() => {
    form.value.clearValidate('roleName');
  })

}
//更新已有的职位按钮的回调
const updateRole = (row) => {
  //显示出对话框
  dialogVisite.value = true;
  //存储已有的职位----带有ID的
  Object.assign(RoleParams, row);
  //清空上一次表单校验错误结果
  nextTick(() => {
    form.value.clearValidate('roleName');
  })
}
//自定义校验规则的回调
const validatorRoleName = (rule, value, callBack) => {
  if (value.trim().length >= 2) {
    callBack();
  } else {
    callBack(new Error('职位名称至少两位'))
  }
}
//职位校验规则
const rules = {
  roleName: [
    {required: true, trigger: 'blur', validator: validatorRoleName}
  ]
}

//确定按钮的回调
const save = async () => {
  //表单校验结果,结果通过在发请求、结果没有通过不应该在发生请求
  await form.value.validate();
  //添加职位|更新职位的请求
  let result = await reqAddOrUpdateRole(RoleParams);
  if (result.code == setting.SYSTEM_SUCCESS) {
    //提示文字
    ElMessage({type: 'success', message: RoleParams.id ? '更新成功' : '添加成功'});
    //对话框显示
    dialogVisite.value = false;
    //再次获取全部的已有的职位
    getHasRole(RoleParams.id ? pageRequest.value.page.index : 1);
  } else {
    //提示文字
    ElMessage({type: 'error', message: result.data});
    //对话框显示
    dialogVisite.value = false;
    //再次获取全部的已有的职位
    getHasRole(RoleParams.id ? pageRequest.value.page.index : 1);
  }
}

//分配权限按钮的回调
//已有的职位的数据
const setPermisstion = async (row) => {
  menuDto.value.roleKey = row.roleKey;
  menuDto.value.roleTime = null;
  //制空被选中
  selectArr.value = [];
  //抽屉显示出来
  drawer.value = true;
  //收集当前要分类权限的职位的数据
  Object.assign(RoleParams, row);
  //根据职位获取权限的数据
  let result = await reqAllMenuList((RoleParams.id));
  if (result.code == setting.SYSTEM_SUCCESS) {
    menuArr.value = result.data;
    //制空被选中
    selectArr.value = filterSelectArr(menuArr.value, []);
  }
}

const defaultProps = {
  children: 'children',
  label: 'menuName',
}

const filterSelectArr = (allData, initArr) => {
  allData.forEach((item) => {
    if (item.isSelect && item.children.length == 0) {
      initArr.push(item.id);
    }
    if (item.children && item.children.length > 0) {
      filterSelectArr(item.children, initArr);
    }
  })
  return initArr;
}

const handlerRole = (row) => {
  getHasRole()
}

//抽屉确定按钮的回调
const handler = async () => {

  if (menuDto.value.roleTime && menuDto.value.roleTime.length === 2) {
    menuDto.value.startTime = menuDto.value.roleTime[0].getTime(); // 开始时间的时间戳
    menuDto.value.endTime = menuDto.value.roleTime[1].getTime(); // 结束时间的时间戳
  }
  //职位的ID
  menuDto.value.roleId = (RoleParams.id);
  menuDto.value.menuIdList = []
  //选中节点的ID
  if (tree.value) {
    let arr = tree.value.getCheckedKeys();
    //半选的ID
    let arr1 = tree.value.getHalfCheckedKeys();
    menuDto.value.menuIdList = arr.concat(arr1);
  }
  //下发权限
  let result = await reqSetPermisstion(menuDto.value);
  if (result.code == setting.SYSTEM_SUCCESS) {
    //抽屉关闭
    drawer.value = false;
    //提示信息
    ElMessage({type: 'success', message: '分配权限成功'});
    //再次获取全部的已有的职位
    getHasRole(RoleParams.id ? pageRequest.value.page.index : 1);
  }
}

//删除已有的职位
const removeRole = async (row) => {
  modal.confirm('确认要删除"' + row.roleName + '"角色吗？').then(async function () {
    let result = await reqRemoveRoles(row.id);
    if (result.code == setting.SYSTEM_SUCCESS) {
      //提示信息
      ElMessage({type: 'success', message: '删除成功'});
      getHasRole(allRole.value.length > 1 ? pageRequest.value.page.index : pageRequest.value.page.index - 1);
    } else {
      //提示文字
      ElMessage({type: 'error', message: result.data});
      //再次获取全部的已有的职位
      getHasRole(RoleParams.id ? pageRequest.value.page.index : 1);
    }
  });
}

//批量删除按钮的回调
const deleteSelectRole = async () => {
  //整理批量删除的参数
  let idsList = selectIdArr.value.map(item => item.id).join(',');
  //批量删除的请求
  let result = await reqRemoveRoles(idsList);
  if (result.code == setting.SYSTEM_SUCCESS) {
    ElMessage({type: 'success', message: '删除成功'});
    getHasRole(allRole.value.length > 1 ? pageRequest.value.page.index : pageRequest.value.page.index - 1);
  } else {
    //提示消息
    ElMessage({type: 'error', message: '删除失败'});
  }
}

const handleStatusChange = async (row) => {
  try {
    // 发送请求更新用户状态
    let result = await reqAddOrUpdateRole(row);
    if (result.code === setting.SYSTEM_SUCCESS) {
      // 更新成功，可以在这里进行其他操作，比如提示用户
      ElMessage({type: 'success', message: '更新成功'});
    }
  } catch (error) {
    // 处理错误
    row.status = row.status === 1 ? 0 : 1;
    //ElMessage({type: 'error', message: '更新失败'});
  }
}
</script>

<style scoped>
.form {
  margin-top: 15px;
  display: flex;
  align-items: center;
}
</style>
